package com.tao.lab.bitmaprecycle;

import android.annotation.TargetApi;
import android.graphics.Bitmap;

import com.tao.lab.utils.Util;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.NavigableMap;
import java.util.TreeMap;

/**
 * @ProjectName: lab
 * @Package: com.tao.lab.bitmaprecycle
 * @ClassName: SizeConfigStrategy
 * @Description: java类作用描述
 * @Author: wangxf
 * @CreateDate: 2022/5/26 9:19
 * @UpdateUser: 更新者
 * @UpdateDate: 2022/5/26 9:19
 * @UpdateRemark: 更新说明
 * @Version: 1.0
 */
@TargetApi(19)
public class SizeConfigStrategy implements LruPoolStrategy {
    private static final int MAX_SIZE_MULTIPLE = 8;
    private static final Bitmap.Config[] ARGB_8888_IN_CONFIGS;
    private static final Bitmap.Config[] RGB_565_IN_CONFIGS;
    private static final Bitmap.Config[] ARGB_4444_IN_CONFIGS;
    private static final Bitmap.Config[] ALPHA_8_IN_CONFIGS;
    private final SizeConfigStrategy.KeyPool keyPool = new SizeConfigStrategy.KeyPool();
    private final GroupedLinkedMap<SizeConfigStrategy.Key, Bitmap> groupedMap = new GroupedLinkedMap();
    private final Map<Bitmap.Config, NavigableMap<Integer, Integer>> sortedSizes = new HashMap();

    public SizeConfigStrategy() {
    }

    public void put(Bitmap bitmap) {
        int size = Util.getBitmapByteSize(bitmap);
        SizeConfigStrategy.Key key = this.keyPool.get(size, bitmap.getConfig());
        this.groupedMap.put(key, bitmap);
        NavigableMap<Integer, Integer> sizes = this.getSizesForConfig(bitmap.getConfig());
        Integer current = (Integer)sizes.get(key.size);
        sizes.put(key.size, current == null ? 1 : current + 1);
    }

    public Bitmap get(int width, int height, Bitmap.Config config) {
        int size = Util.getBitmapByteSize(width, height, config);
        SizeConfigStrategy.Key targetKey = this.keyPool.get(size, config);
        SizeConfigStrategy.Key bestKey = this.findBestKey(targetKey, size, config);
        Bitmap result = (Bitmap)this.groupedMap.get(bestKey);
        if (result != null) {
            this.decrementBitmapOfSize(Util.getBitmapByteSize(result), result.getConfig());
            result.reconfigure(width, height, result.getConfig() != null ? result.getConfig() : Bitmap.Config.ARGB_8888);
        }

        return result;
    }

    private SizeConfigStrategy.Key findBestKey(SizeConfigStrategy.Key key, int size, Bitmap.Config config) {
        SizeConfigStrategy.Key result = key;
        Bitmap.Config[] arr$ = getInConfigs(config);
        int len$ = arr$.length;

        for(int i$ = 0; i$ < len$; ++i$) {
            Bitmap.Config possibleConfig = arr$[i$];
            NavigableMap<Integer, Integer> sizesForPossibleConfig = this.getSizesForConfig(possibleConfig);
            Integer possibleSize = (Integer)sizesForPossibleConfig.ceilingKey(size);
            if (possibleSize != null && possibleSize <= size * 8) {
                if (possibleSize == size) {
                    if (possibleConfig == null) {
                        if (config == null) {
                            break;
                        }
                    } else if (possibleConfig.equals(config)) {
                        break;
                    }
                }

                this.keyPool.offer(key);
                result = this.keyPool.get(possibleSize, possibleConfig);
                break;
            }
        }

        return result;
    }

    public Bitmap removeLast() {
        Bitmap removed = (Bitmap)this.groupedMap.removeLast();
        if (removed != null) {
            int removedSize = Util.getBitmapByteSize(removed);
            this.decrementBitmapOfSize(removedSize, removed.getConfig());
        }

        return removed;
    }

    private void decrementBitmapOfSize(Integer size, Bitmap.Config config) {
        NavigableMap<Integer, Integer> sizes = this.getSizesForConfig(config);
        Integer current = (Integer)sizes.get(size);
        if (current == 1) {
            sizes.remove(size);
        } else {
            sizes.put(size, current - 1);
        }

    }

    private NavigableMap<Integer, Integer> getSizesForConfig(Bitmap.Config config) {
        NavigableMap<Integer, Integer> sizes = (NavigableMap)this.sortedSizes.get(config);
        if (sizes == null) {
            sizes = new TreeMap();
            this.sortedSizes.put(config, sizes);
        }

        return (NavigableMap)sizes;
    }

    public String logBitmap(Bitmap bitmap) {
        int size = Util.getBitmapByteSize(bitmap);
        return getBitmapString(size, bitmap.getConfig());
    }

    public String logBitmap(int width, int height, Bitmap.Config config) {
        int size = Util.getBitmapByteSize(width, height, config);
        return getBitmapString(size, config);
    }

    public int getSize(Bitmap bitmap) {
        return Util.getBitmapByteSize(bitmap);
    }

    public String toString() {
        StringBuilder sb = (new StringBuilder()).append("SizeConfigStrategy{groupedMap=").append(this.groupedMap).append(", sortedSizes=(");
        Iterator i$ = this.sortedSizes.entrySet().iterator();

        while(i$.hasNext()) {
            Map.Entry<Bitmap.Config, NavigableMap<Integer, Integer>> entry = (Map.Entry)i$.next();
            sb.append(entry.getKey()).append('[').append(entry.getValue()).append("], ");
        }

        if (!this.sortedSizes.isEmpty()) {
            sb.replace(sb.length() - 2, sb.length(), "");
        }

        return sb.append(")}").toString();
    }

    private static String getBitmapString(int size, Bitmap.Config config) {
        return "[" + size + "](" + config + ")";
    }

    private static Bitmap.Config[] getInConfigs(Bitmap.Config requested) {
        switch(requested) {
            case ARGB_8888:
                return ARGB_8888_IN_CONFIGS;
            case RGB_565:
                return RGB_565_IN_CONFIGS;
            case ARGB_4444:
                return ARGB_4444_IN_CONFIGS;
            case ALPHA_8:
                return ALPHA_8_IN_CONFIGS;
            default:
                return new Bitmap.Config[]{requested};
        }
    }

    static {
        ARGB_8888_IN_CONFIGS = new Bitmap.Config[]{Bitmap.Config.ARGB_8888, null};
        RGB_565_IN_CONFIGS = new Bitmap.Config[]{Bitmap.Config.RGB_565};
        ARGB_4444_IN_CONFIGS = new Bitmap.Config[]{Bitmap.Config.ARGB_4444};
        ALPHA_8_IN_CONFIGS = new Bitmap.Config[]{Bitmap.Config.ALPHA_8};
    }

    static final class Key implements Poolable {
        private final SizeConfigStrategy.KeyPool pool;
        private int size;
        private Bitmap.Config config;

        public Key(SizeConfigStrategy.KeyPool pool) {
            this.pool = pool;
        }

        Key(SizeConfigStrategy.KeyPool pool, int size, Bitmap.Config config) {
            this(pool);
            this.init(size, config);
        }

        public void init(int size, Bitmap.Config config) {
            this.size = size;
            this.config = config;
        }

        public void offer() {
            this.pool.offer(this);
        }

        public String toString() {
            return SizeConfigStrategy.getBitmapString(this.size, this.config);
        }

        public boolean equals(Object o) {
            if (!(o instanceof SizeConfigStrategy.Key)) {
                return false;
            } else {
                boolean var10000;
                label31: {
                    SizeConfigStrategy.Key other = (SizeConfigStrategy.Key)o;
                    if (this.size == other.size) {
                        if (this.config == null) {
                            if (other.config == null) {
                                break label31;
                            }
                        } else if (this.config.equals(other.config)) {
                            break label31;
                        }
                    }

                    var10000 = false;
                    return var10000;
                }

                var10000 = true;
                return var10000;
            }
        }

        public int hashCode() {
            int result = this.size;
            result = 31 * result + (this.config != null ? this.config.hashCode() : 0);
            return result;
        }
    }

    static class KeyPool extends BaseKeyPool<SizeConfigStrategy.Key> {
        KeyPool() {
        }

        public SizeConfigStrategy.Key get(int size, Bitmap.Config config) {
            SizeConfigStrategy.Key result = (SizeConfigStrategy.Key)this.get();
            result.init(size, config);
            return result;
        }

        protected SizeConfigStrategy.Key create() {
            return new SizeConfigStrategy.Key(this);
        }
    }
}
